package com.yjd.msg.comm.util;

import com.alibaba.fastjson.JSON;
import com.aliyun.mns.client.MNSClient;
import com.aliyun.mns.model.Message;
import com.yjd.comm.base.enums.DbWREnums;

import com.yjd.comm.msg.MnsMsgInfo;
import com.yjd.comm.util.FrameUtil;
import com.yjd.comm.util.ServiceHolder;
import com.yjd.comm.util.SpringContextHolder;
import com.yjd.comm.util.StringUtil;
import com.yjd.msg.comm.core.model.MnsMessage;
import com.yjd.msg.comm.core.service.IMnsDisposeService;
import com.yjd.msg.comm.enums.MsgOrderServiceEnum;
import com.yjd.msg.comm.enums.MsgStatusEnum;
import com.yjd.msg.comm.enums.MsgTypeEnum;
import com.yjd.msg.comm.model.MsgTypeMappedMnsModel;
import com.yjd.msg.comm.service.IMsgInfoService;
import com.yjd.msg.comm.service.IMsgOrderService;
import com.yjd.msg.comm.service.IMsgTypeMappedMnsService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by yjd-wap on 2018/1/11.
 */
public class MnsUtils {
    private static Logger logger = Logger.getLogger(MnsUtils.class);

    /**
     * 保存待发送消息(多条消息)
     */
    private static ThreadLocal<List<MnsMessage>> threadLocalMessageList = new ThreadLocal<>();

    /**
     * 消息处理器
     */
    private static final String MNS_DISPOSE_SERVICE = "mnsDisposeService";

    /**
     * 消息体服务
     */
    private static final String MSGINFOSERVICE = "msgInfoService";


    /**
     * 消息类型和阿里云队列映射
     */
    private static final String MSGTYPEMAPPEDMNSSERVICE ="msgTypeMappedMnsService";


    /**
     * 创建一个消息
     * @param msgId
     * @param msgTypeEnum
     * @param msgOrderServiceEnum
     * @param message
     * @throws Exception
     */
    public static void createMessage(String msgId, MsgTypeEnum msgTypeEnum, MsgOrderServiceEnum msgOrderServiceEnum, Object message) throws Exception {
        if (StringUtils.isBlank(msgId) || msgTypeEnum == null || message == null || msgOrderServiceEnum == null) {
            FrameUtil.throwBaseException1("参数异常");
        }
        List<MnsMessage> mnsList =  new ArrayList<MnsMessage>();
        mnsList.add(getMnsDisposeService().create(msgId,msgTypeEnum,msgOrderServiceEnum,JSON.toJSONString(message)));
        threadLocalMessageList.get().addAll(mnsList);
    }



    /**
     * 发送当前线程中绑定的消息
     *
     * @throws Exception
     */
    public static void sendMessage() throws Exception {
        List<MnsMessage> mnsMessageList = MnsUtils.getMnsMessage();
        if(mnsMessageList != null) {
            for (MnsMessage mnsMessage : mnsMessageList) {
                if (mnsMessage == null || mnsMessage.getMsg_id() == null
                        || mnsMessage.getMsgTypeEnum() == null
                        || mnsMessage.getMsg_order_id() == null) {
                    logger.error("发送当前线程中绑定的消息异常，sendMessage:"+ JSON.toJSONString(mnsMessage));
                } else {
                    // 查询消息是否存在
                    if (!getMnsDisposeService().verify(mnsMessage.getMsg_id(),mnsMessage.getOrder_servcie_name())) {
                        logger.error("源订单表没有找到消息,msg_order_id:" + mnsMessage.getMsg_order_id()
                                + ",消息类型:" + mnsMessage.getMsgTypeEnum());
                    } else {
                        // 发送消息
                        MnsUtils.sendMessage(mnsMessage);
                    }
                }
            }
        }
    }

    /**
     *
     * @param mnsMessage
     */
    @SuppressWarnings("unchecked")
    public static void sendMessage(MnsMessage mnsMessage) {

        try {
            if (mnsMessage != null && mnsMessage.getMsg_id() != null
                    && mnsMessage.getMsgTypeEnum() != null&& StringUtils.isNotBlank(mnsMessage.getContent())) {
                MsgTypeMappedMnsModel msgTypeMappedMnsModel = getMsgTypeMappedMnsService().getModelOne(FrameUtil.newHashMap("msg_type",
                        mnsMessage.getMsgTypeEnum().getCode()), DbWREnums.READ);
                if(msgTypeMappedMnsModel==null){
                    logger.error("消息发送失败，未找到对应的映射消息:"+ JSON.toJSONString(mnsMessage));
                }
                String mns_id = "";
                if(msgTypeMappedMnsModel.getMapped_type().intValue()==1&&msgTypeMappedMnsModel.getStatus().intValue()==1){
                    //发送队列
                    MnsMsgInfo msgInfo = new MnsMsgInfo(mnsMessage.getMsgTypeEnum().getCode(),mnsMessage.getMsg_id(),mnsMessage.getBus_id(),mnsMessage.getContent());
                    Message message =  sendMnsQueue(msgTypeMappedMnsModel.getMns_name(),JSON.toJSONString(msgInfo));
                    mns_id = message.getMessageId();
                }else {
                    //发送主题

                }
                // 发送成功更新发送时间
                getMsgInfoService().updateByMap(FrameUtil.newHashMap("msg_id", mnsMessage.getMsg_id(),
                        "update_time", FrameUtil.getTime(),"mns_id",mns_id,"status", MsgStatusEnum.SUCCESS.getCode()));
            } else {
                logger.error("消息内容异常，未发送消息:"+ JSON.toJSONString(mnsMessage));
            }
        } catch (Exception e) {
            logger.error("发送消息失败,数据："+JSON.toJSONString(mnsMessage)+",异常信息是:" + e.getMessage(), e);
        }
    }


    public static Message sendMnsQueue(String queueName,String message)throws Exception{
        if(StringUtil.isEmpty(queueName)|| StringUtil.isEmpty(message)){
            FrameUtil.throwBaseException1("请求参数不能为空!");
        }
        Message queueMsg = new Message();
        queueMsg.setMessageBody(message.getBytes());
        return getAliyunClient().getQueueRef(queueName).putMessage(queueMsg);

    }

    public static MNSClient getAliyunClient() {
        return ((AliyunClient) SpringContextHolder.getBean("aliyunClient")).getClient();
    }

    /**
     * 获取订单查询服务
     * @return
     */
    public static IMsgOrderService getMsgOrderService(String serviceName)throws Exception{
        return ServiceHolder.getLocalService(IMsgOrderService.class,serviceName);
    }

    public static IMsgTypeMappedMnsService getMsgTypeMappedMnsService()throws Exception{
        return ServiceHolder.getLocalService(IMsgTypeMappedMnsService.class,MSGTYPEMAPPEDMNSSERVICE);
    }

    public static IMsgInfoService getMsgInfoService() {
        return SpringContextHolder.getBean(MSGINFOSERVICE);
    }

    public static IMnsDisposeService getMnsDisposeService() {
        return SpringContextHolder.getBean(MNS_DISPOSE_SERVICE);
    }

    /**
     * 获取当前线程中的消息
     *
     * @return
     */
    public static List<MnsMessage> getMnsMessage() {
        return MnsUtils.threadLocalMessageList.get();
    }

    /**
     * 保存消息到当前线程
     */
    public static void setMnsMessage(List<MnsMessage> msgList) {
        MnsUtils.threadLocalMessageList.set(msgList);
    }

    public static ThreadLocal<List<MnsMessage>> getThreadLocalList() {
        return threadLocalMessageList;
    }
}
